As a reminder, the figure below displays a mile-high view of migration timing across different striped bass spawning groups: Hudson River (HR), Delaware River (DE), and Potomac River (PR). The length of the line displays the range of residence of each group in either the natal estuary (colors) or coastal Massachusetts (yellow). The circle shows the median day of arrival in the given array, and the triangle shows the median date of departure. Only fish that were larger than 800 mm at the time of tagging are shown.
Warning: Invalid .internal.selfref detected and fixed by taking a (shallow)
copy of the data.table so that := can add this new column by reference. At an
earlier point, this data.table has been copied by R (or was created manually
using structure() or similar). Avoid names<- and attr<- which in R currently
(and oddly) may copy the whole data.table. Use set* syntax instead to avoid
copying: ?set, ?setnames and ?setattr. If this message doesn't help, please
report your use case to the data.table issue tracker so the root cause can be
fixed or this message improved.

I’m going to make a quick-and-dirty model to compare the timing of entry into coastal Massachusetts by spawning group. The full model includes day of year (“yday”, numeric), spawning group (“group”, factor), the year (“year”, ordered factor), and all interactions.
The response was modeled as binomial, with the cumulative number of fish that have entered Massachusetts waters per group-year combination considered “successes” and the total number of fish that arrived in coastal MA per group-year combination as the number of trials.
Using step-wise variable selection…
Start: AIC=876.21
cbind(success, trials - success) ~ 0 + group + yday + year +
group:yday + group:year + year:yday + group:year:yday
Df Deviance AIC
<none> 204.73 876.21
- group:yday:year 6 220.74 880.23
…the variables selected are: group, yday, year, group:yday, group:year, yday:year, group:yday:year.
Call:
glm(formula = cbind(success, trials - success) ~ 0 + group +
yday + year + group:yday + group:year + year:yday + group:year:yday,
family = "binomial", data = binom_data[array == "MA Coast"])
Deviance Residuals:
Min 1Q Median 3Q Max
-3.9854 -0.6261 0.0378 0.4881 2.1411
Coefficients:
Estimate Std. Error z value Pr(>|z|)
groupDE -15.875824 1.328794 -11.948 < 2e-16 ***
groupHR -11.264119 1.173194 -9.601 < 2e-16 ***
groupPR -18.541642 2.964276 -6.255 3.97e-10 ***
yday 0.097072 0.008390 11.570 < 2e-16 ***
year.L -8.841642 2.298368 -3.847 0.00012 ***
year.Q -4.173475 2.657588 -1.570 0.11632
year.C 4.614116 2.973727 1.552 0.12075
groupHR:yday -0.033435 0.010911 -3.064 0.00218 **
groupPR:yday 0.014470 0.019871 0.728 0.46650
groupHR:year.L 8.480084 3.853682 2.201 0.02777 *
groupPR:year.L 9.320778 7.243423 1.287 0.19817
groupHR:year.Q -2.710364 3.545181 -0.765 0.44456
groupPR:year.Q 0.729079 6.496961 0.112 0.91065
groupHR:year.C -4.344584 3.207141 -1.355 0.17553
groupPR:year.C 4.656374 5.652772 0.824 0.41009
yday:year.L 0.061693 0.014208 4.342 1.41e-05 ***
yday:year.Q 0.023110 0.016779 1.377 0.16842
yday:year.C -0.033881 0.019006 -1.783 0.07464 .
groupHR:yday:year.L -0.055324 0.023270 -2.377 0.01743 *
groupPR:yday:year.L -0.072239 0.044520 -1.623 0.10467
groupHR:yday:year.Q 0.018236 0.021822 0.836 0.40333
groupPR:yday:year.Q 0.002267 0.039743 0.057 0.95451
groupHR:yday:year.C 0.033170 0.020270 1.636 0.10177
groupPR:yday:year.C -0.013135 0.034307 -0.383 0.70181
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 2656.34 on 202 degrees of freedom
Residual deviance: 204.73 on 178 degrees of freedom
AIC: 876.21
Number of Fisher Scoring iterations: 5
When looking at pairwise contrasts by year, the only significant differences occur in 2018, where arrival in MA was more rapid in DE and PR fish when compared to HR fish (greater yday slope).
year = 2016:
contrast estimate SE df z.ratio p.value
DE - HR -0.00538 0.00971 Inf -0.554 0.8443
DE - PR -0.06700 0.05253 Inf -1.275 0.4091
HR - PR -0.06162 0.05187 Inf -1.188 0.4604
year = 2017:
contrast estimate SE df z.ratio p.value
DE - HR 0.00793 0.00513 Inf 1.547 0.2691
DE - PR -0.02068 0.02399 Inf -0.862 0.6644
HR - PR -0.02861 0.02372 Inf -1.206 0.4494
year = 2018:
contrast estimate SE df z.ratio p.value
DE - HR 0.07717 0.02762 Inf 2.794 0.0144
DE - PR -0.00599 0.03971 Inf -0.151 0.9875
HR - PR -0.08317 0.02924 Inf -2.845 0.0124
year = 2019:
contrast estimate SE df z.ratio p.value
DE - HR 0.05401 0.03196 Inf 1.690 0.2090
DE - PR 0.03579 0.03750 Inf 0.955 0.6056
HR - PR -0.01822 0.04316 Inf -0.422 0.9064
P value adjustment: tukey method for comparing a family of 3 estimates
NOTE: Results may be misleading due to involvement in interactions
$emmeans
year = 2016:
group emmean SE df asymp.LCL asymp.UCL
DE 1.376 0.2072 Inf 0.970 1.782
HR 0.953 0.0709 Inf 0.814 1.092
PR 4.711 1.7653 Inf 1.251 8.171
year = 2017:
group emmean SE df asymp.LCL asymp.UCL
DE 0.738 0.1255 Inf 0.492 0.984
HR 0.364 0.0666 Inf 0.233 0.495
PR 2.738 1.0116 Inf 0.755 4.721
year = 2018:
group emmean SE df asymp.LCL asymp.UCL
DE 4.691 1.0661 Inf 2.602 6.780
HR 0.575 0.1176 Inf 0.344 0.805
PR 1.778 0.4627 Inf 0.871 2.685
year = 2019:
group emmean SE df asymp.LCL asymp.UCL
DE 4.627 0.5827 Inf 3.485 5.769
HR 2.177 0.7645 Inf 0.678 3.675
PR 2.711 0.9279 Inf 0.893 4.530
Results are averaged over the levels of: yday
Results are given on the logit (not the response) scale.
Confidence level used: 0.95
$contrasts
year = 2016:
contrast estimate SE df z.ratio p.value
DE - HR 0.423 0.219 Inf 1.929 0.1304
DE - PR -3.335 1.777 Inf -1.876 0.1455
HR - PR -3.758 1.767 Inf -2.127 0.0844
year = 2017:
contrast estimate SE df z.ratio p.value
DE - HR 0.374 0.142 Inf 2.635 0.0229
DE - PR -2.000 1.019 Inf -1.962 0.1218
HR - PR -2.374 1.014 Inf -2.342 0.0502
year = 2018:
contrast estimate SE df z.ratio p.value
DE - HR 4.116 1.073 Inf 3.838 0.0004
DE - PR 2.913 1.162 Inf 2.506 0.0327
HR - PR -1.203 0.477 Inf -2.521 0.0314
year = 2019:
contrast estimate SE df z.ratio p.value
DE - HR 2.450 0.961 Inf 2.549 0.0291
DE - PR 1.915 1.096 Inf 1.748 0.1875
HR - PR -0.535 1.202 Inf -0.445 0.8967
Results are averaged over the levels of: yday
Results are given on the log odds ratio (not the response) scale.
P value adjustment: tukey method for comparing a family of 3 estimates

Entry into MA waters significantly different between DE and HR fish, but not between PR and HR or PR and DE fish.
Start: AIC=991.5
cbind(success, trials - success) ~ 0 + group + yday + group:yday +
year
Df Deviance AIC
<none> 382.39 991.50
- group:yday 2 394.16 999.26
- year 3 528.96 1132.06
Call:
glm(formula = cbind(success, trials - success) ~ 0 + group +
yday + group:yday + year, family = "binomial", data = binom_data[array ==
"MA Coast"])
Deviance Residuals:
Min 1Q Median 3Q Max
-3.0910 -0.9008 0.0119 0.9630 5.2940
Coefficients:
Estimate Std. Error z value Pr(>|z|)
groupDE -8.542018 0.499708 -17.094 < 2e-16 ***
groupHR -11.015699 0.352014 -31.293 < 2e-16 ***
groupPR -10.413725 1.745313 -5.967 2.42e-09 ***
yday 0.033748 0.001915 17.623 < 2e-16 ***
year2017 -0.374309 0.070063 -5.342 9.17e-08 ***
year2018 0.906559 0.108262 8.374 < 2e-16 ***
year2019 0.300201 0.130164 2.306 0.021092 *
groupHR:yday 0.008022 0.002301 3.486 0.000491 ***
groupPR:yday 0.007858 0.007130 1.102 0.270393
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 2536.41 on 192 degrees of freedom
Residual deviance: 382.39 on 183 degrees of freedom
AIC: 991.5
Number of Fisher Scoring iterations: 5
$emtrends
group yday.trend SE df asymp.LCL asymp.UCL
DE 0.0337 0.00191 Inf 0.0300 0.0375
HR 0.0418 0.00133 Inf 0.0392 0.0444
PR 0.0416 0.00689 Inf 0.0281 0.0551
Results are averaged over the levels of: year
Confidence level used: 0.95
$contrasts
contrast estimate SE df z.ratio p.value
DE - HR -0.008022 0.00230 Inf -3.486 0.0014
DE - PR -0.007858 0.00713 Inf -1.102 0.5127
HR - PR 0.000164 0.00700 Inf 0.023 0.9997
Results are averaged over the levels of: year
P value adjustment: tukey method for comparing a family of 3 estimates

exit times not significantly different

LS0tDQp0aXRsZTogIkVhcmx5IG1pZ3JhdGlvbiBwaGVub2xvZ3kgbW9kZWxzIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFKQ0KYGBgDQoNCkFzIGEgcmVtaW5kZXIsIHRoZSBmaWd1cmUgYmVsb3cgZGlzcGxheXMgYSBtaWxlLWhpZ2ggdmlldyBvZiBtaWdyYXRpb24gdGltaW5nIGFjcm9zcyBkaWZmZXJlbnQgc3RyaXBlZCBiYXNzIHNwYXduaW5nIGdyb3VwczogSHVkc29uIFJpdmVyIChIUiksIERlbGF3YXJlIFJpdmVyIChERSksIGFuZCBQb3RvbWFjIFJpdmVyIChQUikuIFRoZSBsZW5ndGggb2YgdGhlIGxpbmUgZGlzcGxheXMgdGhlIHJhbmdlIG9mIHJlc2lkZW5jZSBvZiBlYWNoIGdyb3VwIGluIGVpdGhlciB0aGUgbmF0YWwgZXN0dWFyeSAoY29sb3JzKSBvciBjb2FzdGFsIE1hc3NhY2h1c2V0dHMgKHllbGxvdykuIFRoZSBjaXJjbGUgc2hvd3MgdGhlIG1lZGlhbiBkYXkgb2YgYXJyaXZhbCBpbiB0aGUgZ2l2ZW4gYXJyYXksIGFuZCB0aGUgdHJpYW5nbGUgc2hvd3MgdGhlIG1lZGlhbiBkYXRlIG9mIGRlcGFydHVyZS4gT25seSBmaXNoIHRoYXQgd2VyZSBsYXJnZXIgdGhhbiA4MDAgbW0gYXQgdGhlIHRpbWUgb2YgdGFnZ2luZyBhcmUgc2hvd24uDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KGx1YnJpZGF0ZSk7IGxpYnJhcnkoZ2dwbG90Mik7IGxpYnJhcnkoZGF0YS50YWJsZSk7IGxpYnJhcnkoZW1tZWFucykNCg0KDQojIHVtY2VzIDwtIGZyZWFkKCdlbWJhcmdvL2Rlcml2ZWQvdW1jZXNfdGFnX2luZm9fZGV0ZWN0aW9ucy5jc3YnKQ0KdW1jZXMgPC0gdGFyX3JlYWQodW1jZXNfZGV0cykNCiMgQXQgdGhpcyBwb2ludCwgaXQgc2VlbXMgdGhhdCBhbGwgb2YgdGhlIE1BLXRhZ2dlZCBmaXNoIGFyZSBIdWRzb24gaW4gb3JpZ2luDQp1bWNlcyA8LSB1bWNlc1tsb2NhdGlvbiA9PSAnTUEgQ29hc3QnLCBncm91cCA6PSAnSFInXQ0KdW1jZXNbbG9jYXRpb24gIT0gJ01BIENvYXN0JywgZ3JvdXAgOj0gZmlmZWxzZShncmVwbCgnMTMwMycsIHRyYW5zbWl0dGVyKSwgJ0hSJywgJ1BSJyldDQoNCmRucmVjIDwtIHRhcl9yZWFkKGRucmVjX2RldHMpDQpkbnJlY1ssIGdyb3VwIDo9ICdERSddDQpkbnJlY1ssIHRsIDo9IHRvdGFsbGVuZ3RoXQ0KDQpkZXRzIDwtIHJiaW5kKHVtY2VzLCBkbnJlYywgZmlsbCA9IFQpDQoNCmRldHMgPC0gZGV0c1tkYXRldGltZSAlYmV0d2VlbiUgYygnMjAxNi0wMS0wMScsICcyMDIwLTAxLTAxJyldDQoNCnN0YXRpb25fa2V5IDwtIGZyZWFkKCdkYXRhL3N0YXRpb25fa2V5LmNzdicpDQpkZXRzIDwtIHN0YXRpb25fa2V5WywgLihhcnJheSwgc3RhdGlvbm5hbWUpXVtkZXRzLCBvbiA9ICdzdGF0aW9ubmFtZSddDQpkZXRzIDwtIGRldHNbYXJyYXkgIT0gJ0ZBTFNFX0RFVCddDQpkZXRzIDwtIGRldHNbIWlzLm5hKGxhdGl0dWRlKV0NCg0KZGV0c1ssICc6PScoaHIgPSBmbG9vcl9kYXRlKGRhdGV0aW1lLCAnaG91cicpLA0KICAgICAgICAgICAgZGF5ID0gZmxvb3JfZGF0ZShkYXRldGltZSwgJ2RheScpLA0KICAgICAgICAgICAgeWVhciA9IHllYXIoZGF0ZXRpbWUpLA0KICAgICAgICAgICAgeWRheSA9IHlkYXkoZGF0ZXRpbWUpKV0NCg0Kcm0odW1jZXMsIGRucmVjKQ0KYGBgDQoNCg0KYGBge3J9DQpwaGVub19taWcgPC0gZGV0c1t0bCA+PSA4MDAsDQogICAgICAgICAgICAgICAgICAuKG1pbl9kYXRlID0gbWluKHlkYXkpLA0KICAgICAgICAgICAgICAgICAgICBtYXhfZGF0ZSA9IG1heCh5ZGF5KSksDQogICAgICAgICAgICAgICAgICBieSA9IGMoJ2dyb3VwJywgJ2FycmF5JywgJ3llYXInLCAndHJhbnNtaXR0ZXInKV0NCg0KcGhlbm9fbWlnIDwtIHBoZW5vX21pZ1ssIA0KICAgICAgICAgICAgICAgICAgICAgICAuKG1pbl9taW4gPSBtaW4obWluX2RhdGUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIG1lZF9taW4gPSBtZWRpYW4obWluX2RhdGUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIG1lZF9tYXggPSBtZWRpYW4obWF4X2RhdGUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIG1heF9tYXggPSBtYXgobWF4X2RhdGUpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBjKCdncm91cCcsICdhcnJheScsICd5ZWFyJyldDQoNCnBoZW5vX21pZyA8LSBwaGVub19taWdbZ3JvdXAgPT0gJ1BSJyAmIGFycmF5ID09ICdQb3RvbWFjJyB8DQogICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPT0gJ0hSJyAmIGFycmF5ID09ICdIdWRzb24nfA0KICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID09J0RFJyAmIGFycmF5ID09ICdEZWxhd2FyZScgfA0KICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5ID09ICdNQSBDb2FzdCddDQoNCnBoZW5vX21pZ1ssIGFycmF5IDo9IGZhY3RvcihhcnJheSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCdQb3RvbWFjJywgJ0RlbGF3YXJlJywgJ0h1ZHNvbicsICdNQSBDb2FzdCcpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUKV0NCg0KcGhlbm9fbWlnWywgZ3JvdXAgOj0gZmFjdG9yKGdyb3VwLA0KICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnUFInLCAnREUnLCAnSFInKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUKV0NCg0KZ2dwbG90KGRhdGEgPSBwaGVub19taWcpICsNCiAgZ2VvbV9saW5lcmFuZ2UoYWVzKHhtaW4gPSBtaW5fbWluLCB4bWF4ID0gbWF4X21heCwgeSA9IGdyb3VwLCANCiAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gYXJyYXkpLA0KICAgICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuNzUpLCBzaXplID0gMSkgKw0KICBnZW9tX3BvaW50KGFlcyh4ID0gbWVkX21pbiwgeSA9IGdyb3VwLCBjb2xvciA9IGFycmF5KSwNCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuNzUpLCBzaXplID0gNSkgKw0KICBnZW9tX3BvaW50KGFlcyh4ID0gbWVkX21heCwgeSA9IGdyb3VwLCBjb2xvciA9IGFycmF5KSwgc2hhcGUgPSAndHJpYW5nbGUnLA0KICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC43NSksIHNpemUgPSA1KSArDQogIGZhY2V0X3dyYXAofiB5ZWFyLCBuY29sID0gMSkgKw0KICBsYWJzKHggPSAnRGF5IG9mIHllYXInLCBzdWJ0aXRsZSA9ICdGaXNoID44MDBtbSBhdCB0YWdnaW5nJykgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpJJ20gZ29pbmcgdG8gbWFrZSBhIHF1aWNrLWFuZC1kaXJ0eSBtb2RlbCB0byBjb21wYXJlIHRoZSB0aW1pbmcgb2YgZW50cnkgaW50byBjb2FzdGFsIE1hc3NhY2h1c2V0dHMgYnkgc3Bhd25pbmcgZ3JvdXAuIFRoZSBmdWxsIG1vZGVsIGluY2x1ZGVzIGRheSBvZiB5ZWFyICgieWRheSIsIG51bWVyaWMpLCBzcGF3bmluZyBncm91cCAoImdyb3VwIiwgZmFjdG9yKSwgdGhlIHllYXIgKCJ5ZWFyIiwgb3JkZXJlZCBmYWN0b3IpLCBhbmQgYWxsIGludGVyYWN0aW9ucy4NCg0KVGhlIHJlc3BvbnNlIHdhcyBtb2RlbGVkIGFzIGJpbm9taWFsLCB3aXRoIHRoZSBjdW11bGF0aXZlIG51bWJlciBvZiBmaXNoIHRoYXQgaGF2ZSBlbnRlcmVkIE1hc3NhY2h1c2V0dHMgd2F0ZXJzIHBlciBncm91cC15ZWFyIGNvbWJpbmF0aW9uIGNvbnNpZGVyZWQgInN1Y2Nlc3NlcyIgYW5kIHRoZSB0b3RhbCBudW1iZXIgb2YgZmlzaCB0aGF0IGFycml2ZWQgaW4gY29hc3RhbCBNQSBwZXIgZ3JvdXAteWVhciBjb21iaW5hdGlvbiBhcyB0aGUgbnVtYmVyIG9mIHRyaWFscy4NCg0KVXNpbmcgc3RlcC13aXNlIHZhcmlhYmxlIHNlbGVjdGlvbi4uLg0KDQpgYGB7cn0NCmJpbm9tX2RhdGEgPC0gZGV0c1t0bCA+PSA4MDAgJg0KICAgICAgICAgICAgICAgICAgICAgKGdyb3VwID09ICdQUicgJiBhcnJheSA9PSAnUG90b21hYycgfA0KICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPT0gJ0hSJyAmIGFycmF5ID09ICdIdWRzb24nfA0KICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPT0nREUnICYgYXJyYXkgPT0gJ0RlbGF3YXJlJyB8DQogICAgICAgICAgICAgICAgICAgICAgICBhcnJheSA9PSAnTUEgQ29hc3QnKV0NCmJpbm9tX2RhdGEgPC0gYmlub21fZGF0YVssIC5TRFt3aGljaC5taW4oeWRheSldLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gYygnZ3JvdXAnLCAnYXJyYXknLCAneWVhcicsICd0cmFuc21pdHRlcicpXQ0KdHJpYWxzIDwtIGJpbm9tX2RhdGFbLCAuKHRyaWFscyA9IC5OKSwgYnkgPSBjKCdncm91cCcsICdhcnJheScsICd5ZWFyJyldDQoNCmJpbm9tX2RhdGEgPC0gYmlub21fZGF0YVssIC5OLCBieSA9IGMoJ2dyb3VwJywgJ2FycmF5JywgJ3llYXInLCAneWRheScpXQ0Kc2V0b3JkZXIoYmlub21fZGF0YSwgZ3JvdXAsIGFycmF5LCB5ZWFyLCB5ZGF5KQ0KYmlub21fZGF0YVssIHN1Y2Nlc3MgOj0gY3Vtc3VtKE4pLCBieSA9IGMoJ2dyb3VwJywgJ2FycmF5JywgJ3llYXInKV0NCg0KYmlub21fZGF0YSA8LSBiaW5vbV9kYXRhW3RyaWFscywgb24gPSBjKCdncm91cCcsICdhcnJheScsICd5ZWFyJyldDQpiaW5vbV9kYXRhWywgeWVhciA6PSBmYWN0b3IoeWVhciwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBzZXEoMjAxNiwgMjAxOSwgMSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFQpXQ0KDQpmdWxsX21vZGVsIDwtIGdsbShjYmluZChzdWNjZXNzLCB0cmlhbHMgLSBzdWNjZXNzKSB+DQogICAgICAgICAgICAgICAgICAwICsgZ3JvdXAgKyB5ZGF5ICsgeWVhciArIGdyb3VwOnlkYXkgKyBncm91cDp5ZWFyICsgeWVhcjp5ZGF5ICsNCiAgICAgICAgICAgICAgICAgICAgZ3JvdXA6eWVhcjp5ZGF5LA0KICAgICAgICAgICAgICAgICAgZGF0YSA9IGJpbm9tX2RhdGFbYXJyYXkgPT0gJ01BIENvYXN0J10sDQogICAgICAgICAgICAgICAgICBmYW1pbHkgPSAnYmlub21pYWwnKQ0KDQptb2RfYXJyaXZhbCA8LSBzdGVwKGZ1bGxfbW9kZWwpDQpgYGANCg0KLi4udGhlIHZhcmlhYmxlcyBzZWxlY3RlZCBhcmU6IGByIHBhc3RlKGNvbG5hbWVzKGF0dHIodGVybXMobW9kX2Fycml2YWwpLCAnZmFjdG9ycycpKSwgY29sbGFwc2UgPSAiLCAiKWAuDQoNCmBgYHtyfQ0Kc3VtbWFyeShtb2RfYXJyaXZhbCkNCmBgYA0KDQpXaGVuIGxvb2tpbmcgYXQgcGFpcndpc2UgY29udHJhc3RzIGJ5IHllYXIsIHRoZSBvbmx5IHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIG9jY3VyIGluIDIwMTgsIHdoZXJlIGFycml2YWwgaW4gTUEgd2FzIG1vcmUgcmFwaWQgaW4gREUgYW5kIFBSIGZpc2ggd2hlbiBjb21wYXJlZCB0byBIUiBmaXNoIChncmVhdGVyIHlkYXkgc2xvcGUpLg0KDQpgYGB7cn0NCmVtdHJlbmRzKG1vZF9hcnJpdmFsLCBwYWlyd2lzZSB+IGdyb3VwIHwgeWVhciwgdmFyID0gInlkYXkiKSRjb250cmFzdHMNCg0KZW1tZWFucyhtb2RfYXJyaXZhbCwgcGFpcndpc2UgfiBncm91cCB8IHllYXIsIGNvdi5rZWVwID0gJ3lkYXknKQ0KDQplbW1pcChtb2RfYXJyaXZhbCwgZ3JvdXAgfiB5ZGF5IHwgeWVhciwgY292LmtlZXAgPSAneWRheScsIENJcyA9IFQpDQpgYGANCg0KDQpgYGB7cn0NCnJhbmdlX2tleSA8LSAgYmlub21fZGF0YVthcnJheSA9PSAnTUEgQ29hc3QnLA0KICAgICAgICAgICAgICAgICAgICAgICAgIC4obWluID0gbWluKHlkYXkpLCBtYXggPSBtYXgoeWRheSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gYygnZ3JvdXAnLCAneWVhcicpXQ0Kc2V0a2V5KHJhbmdlX2tleSwgZ3JvdXAsIHllYXIsIG1pbiwgbWF4KQ0KbmV3X2RhdGEgPC0gZXhwYW5kLmdyaWQoZ3JvdXAgPSBjKCdIUicsICdQUicsICdERScpLA0KICAgICAgICAgICAgICAgICAgICAgICAgeWRheSA9IHNlcShtaW4oYmlub21fZGF0YVthcnJheSA9PSAnTUEgQ29hc3QnXSR5ZGF5KSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4KGJpbm9tX2RhdGFbYXJyYXkgPT0gJ01BIENvYXN0J10keWRheSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aC5vdXQgPSAyMDApLA0KICAgICAgICAgICAgICAgICAgICAgICAgeWVhciA9IGMoJzIwMTYnLCAnMjAxNycsICcyMDE4JywgJzIwMTknKSkNCnNldERUKG5ld19kYXRhKQ0KbmV3X2RhdGFbLCB5ZGF5MiA6PSB5ZGF5XQ0Kc2V0a2V5KG5ld19kYXRhLCAgZ3JvdXAsIHllYXIsIHlkYXksIHlkYXkyKQ0KDQpuZXdfZGF0YSA8LSBmb3ZlcmxhcHMocmFuZ2Vfa2V5LCBuZXdfZGF0YSkNCg0KcHJlZCA8LSBwcmVkaWN0KG1vZF9hcnJpdmFsLA0KICAgICAgICAgICAgICAgIG5ld2RhdGEgPSBuZXdfZGF0YSwNCiAgICAgICAgICAgICAgICB0eXBlID0gJ2xpbmsnLCBzZS5maXQgPSBUKQ0KcHJlZCA8LSBkYXRhLmZyYW1lKG5ld19kYXRhLA0KICAgICAgICAgICAgICAgICAgIHByZWQgPSBwcmVkKQ0KDQpzZXREVChwcmVkKVssICc6PScocHJlZCA9IG1vZF9hcnJpdmFsJGZhbWlseSRsaW5raW52KHByZWQuZml0KSwNCiAgICAgICAgICAgICAgICAgICBsY2kgPSBtb2RfYXJyaXZhbCRmYW1pbHkkbGlua2ludihwcmVkLmZpdCAtIHByZWQuc2UuZml0KSwNCiAgICAgICAgICAgICAgICAgICB1Y2kgPSBtb2RfYXJyaXZhbCRmYW1pbHkkbGlua2ludihwcmVkLmZpdCArIHByZWQuc2UuZml0KSldDQpwbG90bHk6OmdncGxvdGx5KA0KZ2dwbG90KGRhdGEgPSBwcmVkKSArDQogIGdlb21fcmliYm9uKGFlcyh4ID0geWRheSwgeW1heCA9IHVjaSwgeW1pbiA9IGxjaSwgZmlsbCA9IGdyb3VwKSwgYWxwaGEgPSAwLjUpICsNCiAgZ2VvbV9saW5lKGFlcyh4ID0geWRheSwgeSA9IHByZWQsIGdyb3VwID0gZ3JvdXApKSArDQogIGZhY2V0X3dyYXAofnllYXIpICsNCiAgbGFicyhzdWJ0aXRsZSA9ICdNb2RlbGVkIGFycml2YWwgaW4gY29hc3RhbCBNQScpDQopDQpgYGANCg0KRW50cnkgaW50byBNQSB3YXRlcnMgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgYmV0d2VlbiBERSBhbmQgSFIgZmlzaCwgYnV0IG5vdCBiZXR3ZWVuIFBSIGFuZCBIUiBvciBQUiBhbmQgREUgZmlzaC4NCg0KDQpgYGB7cn0NCmJpbm9tX2RhdGEgPC0gZGV0c1t0bCA+PSA4MDAgJg0KICAgICAgICAgICAgICAgICAgICAgKGdyb3VwID09ICdQUicgJiBhcnJheSA9PSAnUG90b21hYycgfA0KICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPT0gJ0hSJyAmIGFycmF5ID09ICdIdWRzb24nfA0KICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPT0nREUnICYgYXJyYXkgPT0gJ0RlbGF3YXJlJyB8DQogICAgICAgICAgICAgICAgICAgICAgICBhcnJheSA9PSAnTUEgQ29hc3QnKV0NCmJpbm9tX2RhdGEgPC0gYmlub21fZGF0YVssIC5TRFt3aGljaC5tYXgoeWRheSldLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gYygnZ3JvdXAnLCAnYXJyYXknLCAneWVhcicsICd0cmFuc21pdHRlcicpXQ0KdHJpYWxzIDwtIGJpbm9tX2RhdGFbLCAuKHRyaWFscyA9IC5OKSwgYnkgPSBjKCdncm91cCcsICdhcnJheScsICd5ZWFyJyldDQoNCmJpbm9tX2RhdGEgPC0gYmlub21fZGF0YVssIC5OLCBieSA9IGMoJ2dyb3VwJywgJ2FycmF5JywgJ3llYXInLCAneWRheScpXQ0Kc2V0b3JkZXIoYmlub21fZGF0YSwgZ3JvdXAsIGFycmF5LCB5ZWFyLCB5ZGF5KQ0KYmlub21fZGF0YVssIHN1Y2Nlc3MgOj0gY3Vtc3VtKE4pLCBieSA9IGMoJ2dyb3VwJywgJ2FycmF5JywgJ3llYXInKV0NCg0KYmlub21fZGF0YSA8LSBiaW5vbV9kYXRhW3RyaWFscywgb24gPSBjKCdncm91cCcsICdhcnJheScsICd5ZWFyJyldDQpiaW5vbV9kYXRhWywgeWVhciA6PSBhcy5mYWN0b3IoeWVhcildDQoNCmZ1bGxfbW9kZWwgPC0gZ2xtKGNiaW5kKHN1Y2Nlc3MsIHRyaWFscyAtIHN1Y2Nlc3MpIH4NCiAgICAgICAgICAgICAgICAgICAwICsgZ3JvdXAgKyB5ZGF5ICsgZ3JvdXA6eWRheSArIHllYXIsDQogICAgICAgICAgICAgICAgICBkYXRhID0gYmlub21fZGF0YVthcnJheSA9PSAnTUEgQ29hc3QnXSwNCiAgICAgICAgICAgICAgICAgIGZhbWlseSA9ICdiaW5vbWlhbCcpDQoNCm1vZF9kZXBhcnR1cmUgPC0gc3RlcChmdWxsX21vZGVsKQ0KYGBgDQoNCmBgYHtyfQ0Kc3VtbWFyeShtb2RfZGVwYXJ0dXJlKQ0KDQplbXRyZW5kcyhtb2RfZGVwYXJ0dXJlLCBwYWlyd2lzZSB+IGdyb3VwLCB2YXIgPSAieWRheSIpDQplbW1pcChtb2RfZGVwYXJ0dXJlLCBncm91cCB+IHlkYXksIGNvdi5yZWR1Y2UgPSByYW5nZSwgQ0lzID0gVCkNCmBgYA0KDQoNCmV4aXQgdGltZXMgbm90IHNpZ25pZmljYW50bHkgZGlmZmVyZW50DQoNCmBgYHtyfQ0KcmFuZ2Vfa2V5IDwtICBiaW5vbV9kYXRhW2FycmF5ID09ICdNQSBDb2FzdCcsDQogICAgICAgICAgICAgICAgICAgICAgICAgLihtaW4gPSBtaW4oeWRheSksIG1heCA9IG1heCh5ZGF5KSksDQogICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBjKCdncm91cCcsICd5ZWFyJyldDQpzZXRrZXkocmFuZ2Vfa2V5LCBncm91cCwgbWluLCBtYXgpDQpuZXdfZGF0YSA8LSBleHBhbmQuZ3JpZChncm91cCA9IGMoJ0hSJywgJ1BSJywgJ0RFJyksDQogICAgICAgICAgICAgICAgICAgICAgICB5ZGF5ID0gc2VxKG1pbihiaW5vbV9kYXRhW2FycmF5ID09ICdNQSBDb2FzdCddJHlkYXkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgoYmlub21fZGF0YVthcnJheSA9PSAnTUEgQ29hc3QnXSR5ZGF5KSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoLm91dCA9IDIwMCksDQogICAgICAgICAgICAgICAgICAgICAgICB5ZWFyID0gYygnMjAxNicsICcyMDE3JywgJzIwMTgnLCAnMjAxOScpKQ0Kc2V0RFQobmV3X2RhdGEpDQpuZXdfZGF0YVssIHlkYXkyIDo9IHlkYXldDQpzZXRrZXkobmV3X2RhdGEsICBncm91cCwgeWRheSwgeWRheTIpDQoNCm5ld19kYXRhIDwtIGZvdmVybGFwcyhyYW5nZV9rZXksIG5ld19kYXRhKQ0KDQpwcmVkIDwtIHByZWRpY3QobW9kX2RlcGFydHVyZSwNCiAgICAgICAgICAgICAgICBuZXdkYXRhID0gbmV3X2RhdGEsDQogICAgICAgICAgICAgICAgdHlwZSA9ICdsaW5rJywgc2UuZml0ID0gVCkNCnByZWQgPC0gZGF0YS5mcmFtZShuZXdfZGF0YSwNCiAgICAgICAgICAgICAgICAgICBwcmVkID0gcHJlZCkNCg0Kc2V0RFQocHJlZClbLCAnOj0nKHByZWQgPSBtb2RfZGVwYXJ0dXJlJGZhbWlseSRsaW5raW52KHByZWQuZml0KSwNCiAgICAgICAgICAgICAgICAgICBsY2kgPSBtb2RfZGVwYXJ0dXJlJGZhbWlseSRsaW5raW52KHByZWQuZml0IC0gcHJlZC5zZS5maXQpLA0KICAgICAgICAgICAgICAgICAgIHVjaSA9IG1vZF9kZXBhcnR1cmUkZmFtaWx5JGxpbmtpbnYocHJlZC5maXQgKyBwcmVkLnNlLmZpdCkpXQ0KDQpnZ3Bsb3QoZGF0YSA9IHByZWQpICsNCiAgZ2VvbV9yaWJib24oYWVzKHggPSB5ZGF5LCB5bWF4ID0gdWNpLCB5bWluID0gbGNpLCBmaWxsID0gZ3JvdXApLCBhbHBoYSA9IDAuNSkgKw0KICBnZW9tX2xpbmUoYWVzKHggPSB5ZGF5LCB5ID0gcHJlZCwgZ3JvdXAgPSBncm91cCkpICsNCiAgZmFjZXRfd3JhcCh+eWVhcikgKw0KICBsYWJzKHN1YnRpdGxlID0gJ01vZGVsZWQgZGVwYXJ0dXJlIGluIGNvYXN0YWwgTUEnKQ0KYGBgDQo=